#include "header.hpp"
using namespace std;

// C++11 thread
// object semantic: copy and assign is not allowed
/* get_id has two versions: member function and normal function
 * 1. invoke by thread object
 * 2. this_thread::get_id()
*/
void threadFunc1(int x){
    cout << endl << "void threadFunc(int)" << endl;
    cout << "child thread id = " << this_thread::get_id() << endl;
    cout << "x = " << x << endl;
}

/* constructor:
 * template< class F, class... Args >
 * explicit thread( F&& f, Args&&... args );
 *
 * f can receive all callable objects such as:
 * (1)normal function
 * (2)function pointer
 * (3)function reference
 * (4)object of the class overloaded operator()
 * (5)Lambda expression
*/

void test9(){
    cout << "main thread id = " << this_thread::get_id() << endl;

    //(1)create by normal function
    thread t1(threadFunc1, 1);

    //(2)create by function pointer
    typedef void (*pFunc)(int);
    pFunc f = &threadFunc1;
    thread t2(f, 2);

    //(3)create by function reference
    typedef void(&pFunc2)(int);
    pFunc2 f2 = threadFunc1;
    thread t3(f2, 3);

    //(4)object of the class overload operator()
    class Example{
    public:
        void operator()(int x){
            cout << endl << "void threadFunc(int)" << endl;
            cout << "child thread id = " << this_thread::get_id() << endl;
            cout << "x = " << x << endl;
        }
    };

    Example ex;
    thread t4(ex, 4);

    //(5)Lambda expression
    thread t5([](int x){
        cout << endl << "void threadFunc(int)" << endl;
        cout << "child thread id = " << this_thread::get_id() << endl;
        cout << "x = " << x << endl;
    }, 5);


    //main thread wait child thread
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    t5.join();
}
